import { Vue } from "./install.js";

const forEach = (obj, fn) => {
  Object.keys(obj).forEach((key) => {
    fn(obj[key], key);
  });
};

class Store {
  constructor(options) {
    // console.log(options);
    // 用户组件中使用的$store = this
    let { state, mutations, actions, module, strict, getters } = options;
    // this.state = state; // 这个状态在页面渲染时需要收集对应的渲染watcher， 这样状态更新才会更新视图
    this.getters = {}; // 我在在取getters属性的时候，把他代理到计算属性上
    this.mutations = {};
    this.actions = {};

    let computed = {};

    // Object.keys(getters).forEach((key) => {
    //   computed[key] = () => {
    //     return getters[key](this.state);
    //   };
    //   // 当我们取getters上取值时， 需要对computed取值
    //   Object.defineProperty(this.getters, key, {
    //     get: () => this._vm[key], // 具备了缓存的功能
    //   });
    // });
    // -------------getters--------------
    forEach(getters, (fn, key) => {
      computed[key] = () => {
        return getters[key](this.state);
      };
      Object.defineProperty(this.getters, key, {
        get: () => this._vm[key],
      });
    });
    // --------------mutations--------------
    forEach(mutations, (fn, key) => {
      this.mutations[key] = (payload) => fn(this.state, payload);
      // commit('changeAge', 10);
      // this.mutation = {changeAge: ()=> {}}
    });
    // --------------actions-----------------
    forEach(actions, (fn, key) => {
      this.actions[key] = (payload) => {
        fn.call(this, this, payload);
      };
    });
    this._vm = new Vue({
      data: {
        // $符号开头的数据不会被挂载到实例上， 但是会挂载到当前的_data上，减少了一次代理
        $$state: state, // 状态在哪里取值， 就会收集对应的
      },
      computed: computed,
    });
    // console.log(this._vm);
  }
  // 类的属性访问器
  get state() {
    // $store.state
    // 依赖于 vue的响应式处理
    return this._vm._data.$$state;
  }
  commit = (type, payload) => {
    // 根据commit还是dispatch 找对应的存储结果
    this.mutations[type](payload);
  };
  dispatch = (type, payload) => {
    this.actions[type](payload);
  };
}

export default Store;
